/**
 * Date: 2022/1/4
 * Author: january
 * Description: 
 */

#include <libecc/cipher/sm4.h>
#include <libecc/utils/utils.h>
#include <libecc/cipher/cipher_mode.h>

int sm4_init(sm4_context* ctx, const u8* iv, int iv_len, const u8* key, int key_len) {
    int ret = -1;
    if (iv_len > SM4_BLOCK_SIZE
        || key_len != SM4_KEY_SIZE) {
        goto out;
    }

    if (iv != NULL) {
        local_memcpy(ctx->nonce, iv, iv_len);
    }
    sm4_gen_rkey(key, &(ctx->rk));

    ret = 0;
    out:
    return ret;
}

void sm4_encrypt_cbc(sm4_context* ctx, const u8* in, int in_len, u8* out) {
    cbc_encrypt(ctx->nonce, SM4_BLOCK_SIZE, &(ctx->rk), (_block_cipher)sm4_encrypt, in, in_len, out);
}

void sm4_decrypt_cbc(sm4_context* ctx, const u8* in, int in_len, u8* out) {
    cbc_decrypt(ctx->nonce, SM4_BLOCK_SIZE, &(ctx->rk), (_block_cipher)sm4_decrypt, in, in_len, out);
}

void sm4_process_ctr(sm4_context* ctx, const u8* in, int in_len, u8* out) {
    ctr_process(ctx->nonce, SM4_BLOCK_SIZE, &(ctx->rk), (_block_cipher)sm4_encrypt, in, in_len, out);
}

void sm4_finalize(sm4_context* ctx) {
    local_memset(ctx, 0, sizeof(*ctx));
}
